package main

import (
	"fmt"
	"strconv"
	"sync"
	"time"
)

const timeFormat string = "2006-01-02 15:04:05"

// 1）在同一个时间段只能有一个goroutine获取到写锁
//
// 2）在同一时间段可以有多个goroutine获取到读锁
//
// 3）在同一时间段只能存在写锁或读锁（读锁和写锁互斥）
func main() {
	var lock sync.RWMutex
	for i := 0; i < 10; i++ {
		go readData("func-READ-"+strconv.Itoa(i), &lock)
	}

	for i := 0; i < 10; i++ {
		go writeData("func-WRITE-"+strconv.Itoa(i), &lock)
	}

	time.Sleep(30 * time.Second)
}

func readData(fun string, lock *sync.RWMutex) {
	defer lock.RUnlock() //释放读锁
	lock.RLock()
	fmt.Println(fun, " get lock at:读", time.Now().Format(timeFormat))
	time.Sleep(time.Second * 1)
	//fmt.Println(fun, " release lock at:读", time.Now())
}

func writeData(fun string, lock *sync.RWMutex) {
	defer lock.Unlock()
	lock.Lock()
	fmt.Println(fun, " get lock at:写WRITE", time.Now().Format(timeFormat))
	time.Sleep(time.Second * 2)
	//fmt.Println(fun, " release lock at:写WRITE", time.Now())
}
